﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Threading;

using HexTD.hex;
using HexTD.tower;
using HexTD.UI;
using HexTD.util;
using HexTD.ExtendNet;

namespace HexTD
{
	public partial class HexTD : PhoneApplicationPage, ContextListener
	{
		public static string NAME = "Hex Tower Defence ";
		public static string VERSION = "0.6.13c";
		public static bool debug = false;

		public enum direction
		{

			NORTH,
			EAST,
			SOUTH,
			WEST,
			UP,
			DOWN,
			LEFT,
			RIGHT
		}

		public enum gameState
		{

			playing,
			editing,
			selecing,
			replaying,
			checking
		}

		private GameBoard gameBoard;
		private LevelSelector levelSelector;

		private string backgroundDefault = "images\\sunset.jpg";
		private Image layer0; // Cache image for the background
		private Image layer1; // Cache image for the hexes
		private bool clearLayer0 = true;
		private bool clearLayer1 = true;
		private bool drawBackground = true;
		//
		int boardWidth, boardHeight;

		private Context context;
		private List<Tower> towers = new List<Tower>();
#if PORT
		private BlackBox blackBoxRecord;
		private BlackBox blackBoxPlayback;
#endif
		private bool autoLaunch = false;
		private bool startWave = false;
		private bool startWaveDelayed = false;
		private bool waveReady = true;
		private bool placingTower = false;

		private TowerFactory.type placingTowerType;

		private float placingTowerRange = 0;
		private int graceTicks = 0;
		private int graceTicksMax = 5;
		private int paintTime = 0;
		//
		private Object paintTimeLock = new Object();
		private Object paintLock = new Object();
		private bool painting = false;
		private bool noSleep = false;
		private bool noPaint = false;
		//
		private colorSelection colors = new colorSelection();
		//
		private int tickTime = 50;
		private int tickTimeSkip = 0;
		private int tickTimeFast = 15;
		private int tickTimeNormal = 50;
		private bool paused = false;
		private bool gameStopped = false;
		private int[] highlightedHex;
		private int lastPaddedLeft = -1;

		private static string form = "#,###.##";

		private string scorePostUrl = "";
		private string scoreFetchUrl = "";
		private int score_id;
		private string mode;
		private Thread gameLogicThread;
		private bool running = true;

		// Constructor
		public HexTD()
		{
			InitializeComponent();

			init();
		}

		/** Creates a new instance of NewJApplet */
		public void init()
		{
			System.Diagnostics.Debug.WriteLine(HexTD.NAME + " v" + HexTD.VERSION);

#if PORT_FEAT
		try {
			this.scorePostUrl = new URL(ParameterUtils.paramToUrl(this, "postUrl", "http://pkedu.fbt.wur.nl/~hylke/hextd/dev/postscore.php"));
			this.scoreFetchUrl = new URL(ParameterUtils.paramToUrl(this, "fetchUrl", "http://pkedu.fbt.wur.nl/~hylke/hextd/dev/fetchreplay.php"));
		} catch (MalformedURLException ex) {
			Logger.getLogger(HexTD.class.getName()).log(Level.SEVERE, null, ex);
		}
#endif

#if PORT_FEAT
			this.mode = ParameterUtils.paramToString(this, "mode", "play");
			this.score_id = ParameterUtils.paramToInt(this, "score_id", 0);
#else
			this.mode = "play";
#endif

			this.score_id = 0;
			System.Diagnostics.Debug.WriteLine("HexTD: score post url: " + this.scorePostUrl.ToString());

			this.context = new Context(this);
#if PORT
			// This call results in the Application startpath?
			// Result in Java: "/C:/Users/Mathijs/Documents/Visual%20Studio%202010/Projects/ROOT_HexTD/branches/Original_Y2010M09D05/HexTD/trunk/build/classes/hextd/"
			this.context.contextUrl = getClass().getResource("/hextd/");
#endif
			this.context.VERSION = HexTD.VERSION;
			this.towers = this.context.towers;

			this.context.addContextListener(this);
			this.context.waveStarted += new EventHandler(waveStart);

			this.gameBoard = new GameBoard(this, this.context);
			initComponents();
			this.context.colors = this.colors;

#if PORT_FEAT
			this.blackBoxRecord = new BlackBox(this.context, this);
			this.blackBoxPlayback = new BlackBox(this.context, this);
			this.context.blackBoxCurrent = this.blackBoxRecord;
#endif

			this.DebugTextBlock.Visibility = HexTD.debug ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;

			this.levelSelector = new LevelSelector(MapsListBox);
			this.levelSelector.setContext(this.context, this);

#if PORT
			this.panelWaveInfo.setContext(this.context);
			this.jPanelTowerSelector.doInit(this.context, this);
			this.panelTowerInfo.setContext(this.context);
			this.jPanelPathEditor.setContext(this.context);
			this.panelReplayControls.setContext(this.context, this);
			this.panelReplayControls.setBlackBox(this.blackBoxRecord, this.blackBoxPlayback);
#endif

#if PORT
			GridBagConstraints gridBagConstraints = new GridBagConstraints();
			gridBagConstraints.gridx = 0;
			gridBagConstraints.gridy = 1;
			gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
			gridBagConstraints.weightx = 0.1;
			gridBagConstraints.weighty = 0.1;
			this.jPanel_board.Add(this.gameBoard, gridBagConstraints);
#endif

			this.levelSelector.loadIndex("maps\\levels.txt");
#if PORT
			if (this.mode.equalsIgnoreCase("check") && this.score_id > 0) {
				// We are reviewing a topscore
				System.Diagnostics.Debug.WriteLine("HexTD: Check mode: " + this.score_id);
				this.context.gameState = HexTD.gameState.checking;
				this.blackBoxPlayback.loadLog(this.loadReplay(this.scoreFetchUrl));
			} else if (this.mode.equalsIgnoreCase("watch") && this.score_id > 0) {
				// We are reviewing a topscore
				System.Diagnostics.Debug.WriteLine("HexTD: Watch mode: " + this.score_id);
				this.context.gameState = HexTD.gameState.replaying;
				this.blackBoxPlayback.loadLog(this.loadReplay(this.scoreFetchUrl));
			} else {
				// Normal game
				System.Diagnostics.Debug.WriteLine("HexTD: Game mode");
			}
			this.setUI();
#endif

			this.recalculateScale();
			// Create the gameLogic thread and start it.
			this.gameLogicThread = new Thread(new ThreadStart(this.run));
			this.gameLogicThread.Name = "gameLogicThread";
			this.gameLogicThread.Start();

			if (System.String.Equals(this.mode, "check", StringComparison.OrdinalIgnoreCase) && this.score_id > 0)
			{
#if PORT
				// We are reviewing a topscore
				this.panelReplayControls.skipTillEnd();
#endif
			}
		}

		public string getStatusMessage()
		{
			return "<h1>Shortcut keys</h1>" +
					"<p>" +
					"<b>P</b>: Pause<br>" +
					"<b>F</b>: Fast-Forward<br>" +
					"<b>S</b>: Sell (<b>Y</b>es/<b>N</b>o)<br>" +
					"<b>U</b>: Upgrade<br>" +
					"<b>W</b>: Next Wave<br>" +
					"<b>T</b>: Next Targeting mode<br>" +
					"</p>" +
					"<h1>Interest</h1>" +
					"<p>Interest is " + this.context.interestStart + "% plus " + this.context.interestIncrease + "% per unspend bonus point.</p>" +
					"<h1>Upgrades</h1>" +
					"<p>Upgrades increase damage with 45% and range with 7%.</p>";
		}

		public void setInfoText(String s)
		{
			this.unSelectTower();
#if PORT
			this.panelTowerInfo.setExternalText(s);
#endif
		}

		private void waveStart(object sender, EventArgs e)
		{
			NextWaveButton.IsEnabled = false;
			setWavePreview();
		}

		public void enemyDied(int enemiesLeft)
		{
			if (enemiesLeft == 0 && this.context.getWave() < this.context.getWaveCount())
			{
				System.Diagnostics.Debug.WriteLine("HexTD::enemyDied: " + this.context.gameTime + " Last enemy died.");
				this.waveReady = true;
				this.context.setWaveActive(false);
				this.graceTicks = this.graceTicksMax;
				if (this.context.gameState == gameState.playing)
				{
					if (this.autoLaunch)
					{
						this.startWave = true;
					}
					else
					{
#if PORT
						this.jButton_nextWave.setEnabled(true);
#endif
					}
				}
				if (this.context.gameState == gameState.checking || this.context.gameState == gameState.replaying)
				{
					// If we're checking we don't want the game to "hang" because the wave is not launced.
					this.startWaveDelayed = true;
				}
			}
			else if (enemiesLeft == 0 && this.context.getWave() >= this.context.getWaveCount())
			{
				this.context.setWaveActive(false);
				this.gameWon();
			}
		}

		public void setWavePreview()
		{
#if PORT
		this.panelWaveInfo.clearWaves();
		int wave = this.context.getWave();
		Vector<Wave> waves = this.context.getWaves();
		if (wave - 1 >= 0) {
			this.panelWaveInfo.setWaveCur(waves.get(wave - 1));
		}
		if (wave < waves.Count) {
			this.panelWaveInfo.setWaveNext(waves.get(wave));
		}
#endif
		}

		private void nextWave()
		{
			if (this.waveReady && this.context.getWave() < this.context.getWaveCount())
			{
				this.startWave = false;
				this.startWaveDelayed = false;
				this.waveReady = false;

#if PORT
			this.blackBoxRecord.nextWave();
#endif

				this.NextWaveButton.IsEnabled = false;
				this.updateInfo();
			}
			if (this.paused)
			{
				this.setPause(false);
			}
		}

		private void updateInfo()
		{
#if PORT
		this.jLabel_wave.setText("" + this.context.getWave() + "/" + this.context.getWaveCount());
		this.jLabel_credits.setText("â‚¬" + HexTD.form.format(this.context.getCredits()) + "");
		this.jLabel_lives.setText("" + this.context.getLives());
		this.jLabel_interest.setText("" + this.context.getInterest() + "%");
		this.jLabel_bonus.setText("" + this.context.getBonus());
		this.jLabel_score.setText("" + HexTD.form.format(this.context.getScore()));
		this.jSpinner_height.setValue(new Integer(this.context.gridHeight));
		this.jSpinner_width.setValue(this.context.gridWidth);
#endif
		}

		public void moneyChanged()
		{
			this.updateInfo();
		}

		public void livesChanged()
		{
			this.updateInfo();
			if (this.context.getLives() <= 0)
			{
				this.gameLost();
			}
		}

		public void interestChanged()
		{
			this.updateInfo();
		}

		private void gameLost()
		{
#if PORT
		this.gameStopped = true;
		this.endMaxGameSpeed();
		this.gameBoard.setVisible(false);
		this.jButton_postScore.setEnabled(true);
		this.jLabel_submitFeedback.setText("");
		this.jPanel_GameWon.setVisible(false);
		if (this.context.gameState == HexTD.gameState.playing) {
			this.jPanel_GameLost.setVisible(true);
			this.jPanel_replayEnded.setVisible(false);
			if (!this.context.mapLocation.equals("Custom")) {
				this.jPanel_submitScore.setVisible(true);
			}
			this.jPanel_submitReview.setVisible(false);
		} else if (this.context.gameState == HexTD.gameState.checking) {
			this.jPanel_GameLost.setVisible(false);
			this.jPanel_replayEnded.setVisible(true);
			this.jPanel_submitScore.setVisible(false);
			this.jPanel_submitReview.setVisible(true);
		} else {
			this.jPanel_GameLost.setVisible(false);
			this.jPanel_replayEnded.setVisible(true);
			this.jPanel_submitScore.setVisible(false);
			this.jPanel_submitReview.setVisible(false);
		}
#endif
		}

		private void gameWon()
		{
#if PORT
		this.gameStopped = true;
		this.endMaxGameSpeed();
		this.gameBoard.setVisible(false);
		this.jButton_postScore.setEnabled(true);
		this.jLabel_submitFeedback.setText("");
		this.jPanel_GameLost.setVisible(false);
		if (this.context.gameState == HexTD.gameState.playing) {
			this.jPanel_GameWon.setVisible(true);
			this.jPanel_replayEnded.setVisible(false);
			if (!this.context.mapLocation.equals("Custom")) {
				this.jPanel_submitScore.setVisible(true);
			}
			this.jPanel_submitReview.setVisible(false);
		} else if (this.context.gameState == HexTD.gameState.checking) {
			this.jPanel_GameWon.setVisible(false);
			this.jPanel_replayEnded.setVisible(true);
			this.jPanel_submitScore.setVisible(false);
			this.jPanel_submitReview.setVisible(true);
		} else {
			this.jPanel_GameWon.setVisible(false);
			this.jPanel_replayEnded.setVisible(true);
			this.jPanel_submitScore.setVisible(false);
			this.jPanel_submitReview.setVisible(false);
		}
#endif
		}

		public void mapChanged()
		{
			this.levelSelector.setLevelInfo("<h1>" + this.context.levelTitle + "</h1>" + this.context.levelInfo);
			this.AutoLaunchCheckBox.IsChecked = false;
			this.recalculateScale();
#if PORT
		this.updateInfo();
#endif
		}

		public void resetMap()
		{
			this.graceTicks = this.graceTicksMax;
		}

		public void startLevel()
		{
			this.AutoLaunchCheckBox.IsChecked = false;
			this.gameStopped = true;
#if PORT_FEAT
			this.blackBoxRecord.clear();
			this.blackBoxRecord.startMap(this.context.mapLocation);
#endif
			this.updateInfo();
			this.setWavePreview();
			this.waveReady = true;
			this.context.gameState = gameState.playing;
			this.setUI();
			this.gameStopped = false;
		}

		private void setGameButtons(bool enabled)
		{
#if PORT
		this.jButton_nextWave.setEnabled(enabled);
		this.jCheckBox_autoLaunch.setEnabled(enabled);
		this.jCheckBox_fastForward.setEnabled(enabled);
#endif
		}

		public void setUI()
		{
#if PORT
		if (!this.context.isWaveActive() && !this.autoLaunch) {
			this.jButton_nextWave.setEnabled(true);
		} else {
			this.jButton_nextWave.setEnabled(false);
		}
		this.jPanel_GameLost.setVisible(false);
		this.jPanel_GameWon.setVisible(false);
		this.jPanel_replayEnded.setVisible(false);
		this.jPanel_submitScore.setVisible(false);
		this.jPanel_submitReview.setVisible(false);
		this.gameBoard.setVisible(true);
		switch (this.context.gameState) {
			case editing:
				this.context.mapLocation = "Custom";
				this.setGameButtons(false);

				this.jPanelTowerSelector.setVisible(false);
				this.jPanel_gameInfo.setVisible(false);
				this.panelWaveInfo.setVisible(false);
				this.jPanel_editor.setVisible(true);
				this.jPanelPathEditor.setVisible(true);
				this.jPanelLevelSelector.setVisible(false);
				this.panelReplayControls.setVisible(false);

				this.jPanelPathEditor.resetPaths();
				this.jSpinner_interestStart.setValue(this.context.interestStart);
				this.jSpinner_interestIncrease.setValue(this.context.interestIncrease);
				this.jSpinner_moneyStart.setValue(this.context.creditsStart);
				this.jSpinner_lives.setValue(this.context.livesStart);
				this.jTextField_background.setText(this.context.backgroundImage);
				this.jTextField_title.setText(this.context.levelTitle);

				this.panelTowerInfo.setVisible(false);

				this.jMenuItem_ReplayCenter.setEnabled(false);
				this.jMenuItem_editLevel.setEnabled(false);
				this.jMenuItem_exitLevel.setEnabled(true);
				this.jMenuItem_restartLevel.setEnabled(true);
				break;
			case playing:
				this.setGameButtons(true);

				this.jPanelTowerSelector.setVisible(true);
				this.jPanel_gameInfo.setVisible(true);
				this.panelWaveInfo.setVisible(true);
				this.jPanel_editor.setVisible(false);
				this.jPanelPathEditor.setVisible(false);
				this.jPanelLevelSelector.setVisible(false);
				this.panelReplayControls.setVisible(false);

				this.panelTowerInfo.setExternalText(this.getStatusMessage());
				this.jCheckBox_autoLaunch.setEnabled(true);

				this.jMenuItem_ReplayCenter.setEnabled(true);
				this.jMenuItem_editLevel.setEnabled(true);
				this.jMenuItem_exitLevel.setEnabled(true);
				this.jMenuItem_restartLevel.setEnabled(true);
				break;
			case selecing:
				this.setGameButtons(false);

				this.jPanelTowerSelector.setVisible(false);
				this.jPanel_gameInfo.setVisible(false);
				this.panelWaveInfo.setVisible(false);
				this.jPanel_editor.setVisible(false);
				this.jPanelPathEditor.setVisible(false);
				this.jPanelLevelSelector.setVisible(true);
				this.panelReplayControls.setVisible(false);

				this.panelTowerInfo.setVisible(false);

				this.jMenuItem_ReplayCenter.setEnabled(true);
				this.jMenuItem_editLevel.setEnabled(true);
				this.jMenuItem_exitLevel.setEnabled(false);
				this.jMenuItem_restartLevel.setEnabled(false);
				break;
			case replaying:
			case checking:
				this.setGameButtons(false);
				this.jCheckBox_fastForward.setEnabled(true);

				this.jPanelTowerSelector.setVisible(false);
				this.jPanel_gameInfo.setVisible(true);
				this.panelWaveInfo.setVisible(true);
				this.jPanel_editor.setVisible(false);
				this.jPanelPathEditor.setVisible(false);
				this.jPanelLevelSelector.setVisible(false);
				this.panelReplayControls.setVisible(true);
				this.jCheckBox_autoLaunch.setEnabled(false);
				this.jCheckBox_autoLaunch.setSelected(false);

				this.panelTowerInfo.setVisible(false);

				this.jMenuItem_ReplayCenter.setEnabled(false);
				this.jMenuItem_editLevel.setEnabled(false);
				if (this.context.gameState == HexTD.gameState.replaying) {
					this.jMenuItem_exitLevel.setEnabled(true);
					this.jMenuItem_restartLevel.setEnabled(true);
				} else {
					this.jMenuItem_exitLevel.setEnabled(false);
					this.jMenuItem_restartLevel.setEnabled(false);
				}
				this.gameStopped = false;
				break;
		}
#endif
		}

		public void recalculateScale()
		{
			float scale;

			this.context.getCache().clearCache();

			this.boardWidth = (int)this.GameBoardCanvas.RenderSize.Width;
			this.boardHeight = (int)this.GameBoardCanvas.RenderSize.Height;
			if (this.boardHeight == 0)
			{
				this.boardWidth = 400;
				this.boardHeight = 300;
			}
			layer0 = new Image();
			layer1 = new Image();

			float xScale = (this.boardWidth - 2) / (2f * ((float)Math.Sin(Math.PI / 3)) * this.context.gridWidth);
			float yScale = (this.boardHeight - 2) / (1.5f * (this.context.gridHeight + 0.5f));

			scale = Math.Min(xScale, yScale);
			this.context.paintScale = scale;
			this.context.strokeScale = scale / 40f;
			this.context.hexFloatWidth = (float)Math.Sin(Math.PI / 3);
			this.context.hexPaintWidth = this.context.hexFloatWidth * scale;

			this.context.offsetX = ((float)boardWidth - scale * 2f * ((float)Math.Sin(Math.PI / 3)) * this.context.gridWidth) / 2f;
			this.context.offsetY = ((float)boardHeight - 1.5f * scale * (this.context.gridHeight + 0.5f)) / 2;
			this.context.minX = 0;
			this.context.minY = 0;
			this.context.maxX = (2f * ((float)Math.Sin(Math.PI / 3)) * this.context.gridWidth);
			this.context.maxY = (1.5f * (this.context.gridHeight + 0.5f));
			//System.Diagnostics.Debug.WriteLine("New scale: "+xScale+" "+yScale+" "+scale);
			//System.Diagnostics.Debug.WriteLine("New Offsets: "+this.offsetX+" "+this.offsetY);
			if (this.context.grid != null)
			{
				for (int y = 0; y < this.context.grid.GetLength(1); y++)
				{
					int xLength = this.context.grid.GetLength(0) - (y & 1);
					for (int x = 0; x < xLength; x++)
					{
						this.context.grid[x, y].resetScale();
					}
				}
			}
			if (this.context.enemies != null)
			{
				for (int i = 0; i < this.context.enemies.Length; i++)
				{
					this.context.enemies[i].resetScale();
				}
			}
			for (int i = 0; i < this.towers.Count; i++)
			{
				this.towers[i].resetScale();
			}
			List<wave.Path> paths = this.context.getPaths();
			for (int i = 0; i < paths.Count; i++)
			{
				paths[i].resetScale();
			}

			this.clearLayer0 = true;
			this.clearLayer1 = true;
		}

		public void doTick(int time)
		{
			if (this.context.enemies != null)
			{
				for (int i = 0; i < this.context.enemies.Length; i++)
				{
					this.context.enemies[i].doTick(time);
				}
			}
			for (int i = 0; i < this.towers.Count; i++)
			{
				this.towers[i].doTick(time);
			}
			if (this.startWave)
			{
				this.nextWave();
			}
		}

		public void paintBoard(Canvas g2)
		{
			lock (this.paintLock)
			{
				this.painting = true;
			}
			int time;
			// Two layers for the background (hexes) that are cached.
#if PORT_REM
		Graphics2D g2_0 = null;
		Graphics2D g2_1 = null;
#endif
			bool clearedLayer0 = false;
			bool clearedLayer1 = false;

			lock (this.paintTimeLock)
			{
				time = this.paintTime;
			}

			lock (this.context.PaintingLock)
			{
#if PORT_FEAT
			this.panelWaveInfo.doTick(time);
#endif

				//long time1 = new Date().getTime();

				if (this.clearLayer0)
				{
					//System.Diagnostics.Debug.WriteLine("Redrawing layer 0...");
					this.clearLayer0 = false;
					clearedLayer0 = true;

					GameBoardCanvas.Children.Clear();

					if (this.drawBackground)
					{
						string bgPath = (this.context.backgroundImage.Length > 0) ?
							this.context.backgroundImage :
							this.backgroundDefault;

						ImageBrush bgBrush = new ImageBrush();
						bgBrush.ImageSource = new BitmapImage(new Uri(bgPath, UriKind.Relative));
						bgBrush.Stretch = Stretch.Fill;

						GameBoardCanvas.Background = bgBrush;
					}
				}

				if (this.clearLayer1)
				{
					//System.Diagnostics.Debug.WriteLine("Redrawing layer 1...");
					this.clearLayer1 = false;
					clearedLayer1 = true;

					GameBoardCanvas.Children.Clear();
				}

				if (clearedLayer0 || clearedLayer1)
				{
					if (this.context.grid != null)
					{
						for (int y = 0; y < this.context.grid.GetLength(1); y++)
						{
							int xLength = this.context.grid.GetLength(0) - (y & 1);
							for (int x = 0; x < xLength; x++)
							{
								this.context.grid[x, y].paintBase(GameBoardCanvas, null);
							}
						}
					}
				}

#if PORT_REM
			if (g2_0 != null) {
				g2_0.dispose();
			}
			if (g2_1 != null) {
				g2_1.dispose();
			}

			g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
			g2.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
			g2.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
			g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));

			// Draw the cached background.
			g2.drawImage(this.layer0, 0, 0, null);
#endif

				if (this.context.grid != null)
				{
					for (int y = 0; y < this.context.grid.GetLength(1); y++)
					{
						int xLength = this.context.grid.GetLength(0) - (y & 1);
						for (int x = 0; x < xLength; x++)
						{
							this.context.grid[x, y].paintEffects(g2);
						}
					}
				}
				List<wave.Path> paths = this.context.getPaths();
				for (int i = paths.Count - 1; i >= 0; i--)
				{
					paths[i].paint(g2, time);
				}

				if (this.context.enemies != null)
				{
					for (int i = 0; i < this.context.enemies.Length; i++)
					{
						this.context.enemies[i].paint(g2, time);
					}
				}

				for (int i = 0; i < this.towers.Count; i++)
				{
					this.towers[i].paint(g2, time);
				}

				for (int i = 0; i < this.towers.Count; i++)
				{
					this.towers[i].paintEffects(g2, time);
				}
			}
			//long time2 = new Date().getTime();
			//this.jLabel_time.setText(""+(time2-time1));
			lock (this.paintLock)
			{
				this.painting = false;
			}
		}

		public void startPlacing(TowerFactory.type t, float r)
		{
			this.placingTower = true;
			this.placingTowerType = t;
			this.placingTowerRange = r;
		}

		public void unSelectTower()
		{
#if PORT
		this.unHighLighHex();
		this.panelTowerInfo.unselectTower();
		if (this.context.gameState == gameState.playing) {
			this.panelTowerInfo.setExternalText(this.getStatusMessage());
		}
#endif
		}

		public void unHighLighHex()
		{
#if PORT
		if (this.highlightedHex != null &&
				this.context.grid[this.highlightedHex[0]] != null &&
				this.context.grid[this.highlightedHex[0], this.highlightedHex[1]] != null) {
			this.context.grid[this.highlightedHex[0], this.highlightedHex[1]].setHighlight(Hex.highlightType.none);
		}
		this.highlightedHex = null;
#endif
		}

		public void highLightHex(Hex h, hex.highlightType t)
		{
#if PORT
		this.unHighLighHex();
		h.setHighlight(t);
		this.highlightedHex = h.getLocation();
#endif
		}

		public void highLightHex(int[] hexC)
		{
#if PORT
		int col = hexC[0];
		int row = hexC[1];
		this.unHighLighHex();
		if (row >= 0 && row < this.context.gridHeight) {
			if (col >= 0 && col < (this.context.gridWidth - (row & 1))) {
				this.highlightedHex = hexC;
				if (this.context.gameState == HexTD.gameState.editing) {
					this.context.grid[col, row].setHighlight(Hex.highlightType.editHex);
				} else if (this.placingTower) {
					this.context.grid[col, row].setHighlight(Hex.highlightType.placeTower);
					this.context.grid[col, row].setHighlightRange(this.placingTowerRange);
				}
			}
		}
#endif
		}

		public static void main(String[] s)
		{
#if PORT_REM
		JFrame f = new JFrame("HexTD");
		f.addWindowListener(new WindowAdapter() {

			public override void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		JApplet applet = new HexTD();
		f.getContentPane().Add("Center", applet);
		init();
		f.pack();
		f.setSize(new Dimension(800, 600));
		f.setVisible(true);
#endif
		}

		private void toggleGameSpeed()
		{
			lock (this.context.gameTimeLock)
			{
				this.noSleep = !this.noSleep;
				this.FastModeCheckBox.IsChecked = this.noSleep;
				if (this.noSleep)
				{
					this.tickTime = this.tickTimeFast;
				}
				else
				{
					this.tickTime = this.tickTimeNormal;
				}
			}
		}

		public void togglePause()
		{
			this.setPause(!this.paused);
		}

		public void setPause(bool p)
		{
#if PORT
		this.paused = p;
		if (this.paused) {
			this.jLabel_gameTitle.setText("          Paused           ");
		} else {
			this.jLabel_gameTitle.setText(HexTD.NAME);
		}
#endif
		}

		public void setMaxGameSpeed()
		{
			lock (this.context.gameTimeLock)
			{
				this.noPaint = true;
				this.tickTime = this.tickTimeSkip;
			}
		}

		public void endMaxGameSpeed()
		{
			lock (this.context.gameTimeLock)
			{
				this.noPaint = false;
				if (this.noSleep)
				{
					this.tickTime = this.tickTimeFast;
				}
				else
				{
					this.tickTime = this.tickTimeNormal;
				}
			}
		}

		private void resizeGrid()
		{
			if (this.context.gameState == HexTD.gameState.editing)
			{
#if PORT
			int paddingLeft = 0;
			int paddingTop = 0;
			int cutLeft = 0;
			int cutTop = 0;
			int oddLeftPadding = 0;
			bool top = this.jCheckBox_addTop.isSelected();
			try {
				this.context.gridWidth = new Integer(this.jSpinner_width.getValue().toString()).intValue();
				this.context.gridHeight = new Integer(this.jSpinner_height.getValue().toString()).intValue();
			} catch (NumberFormatException e) {
			}

			Hex[, ] newGrid = new Hex[this.context.gridWidth, this.context.gridHeight];
			if (this.jCheckBox_addLeft.isSelected()) {
				if (newGrid.GetLength(0) > this.context.grid.GetLength(0)) {
					paddingLeft = newGrid.GetLength(0) - this.context.grid.GetLength(0);
				} else {
					cutLeft = this.context.grid.GetLength(0) - newGrid.GetLength(0);
				}
			}

			if (top) {
				if (newGrid.GetLength(1) > this.context.grid.GetLength(1)) {
					paddingTop = newGrid.GetLength(1) - this.context.grid.GetLength(1);
				} else {
					cutTop = this.context.grid.GetLength(1) - newGrid.GetLength(1);
				}
			}

			if (top && (((paddingTop - cutTop) & 1) == 1)) {
				// padding left needed on odd rows
				oddLeftPadding = -this.lastPaddedLeft;
				this.lastPaddedLeft = oddLeftPadding;
			}

			for (int y = cutTop; y < this.context.grid.GetLength(1); y++) {
				bool odd = ((y & 1) == 1);
				if (oddLeftPadding < 0) {
					odd = !odd;
				}
				int xLength = this.context.grid.GetLength(0) - (y & 1);
				int thisPadLeft = odd ? oddLeftPadding : 0;
				if ((y < this.context.grid.GetLength(1)) &&
						(y >= 0) &&
						(y + paddingTop - cutTop < newGrid.GetLength(1)) &&
						(y + paddingTop - cutTop >= 0)) {
					for (int x = cutLeft - thisPadLeft; x < xLength; x++) {
						if (x < newGrid.GetLength(0) && x >= 0) {
							newGrid[x + paddingLeft - cutLeft + thisPadLeft, y + paddingTop - cutTop] = this.context.grid[x, y];
							newGrid[x + paddingLeft - cutLeft + thisPadLeft, y + paddingTop - cutTop].setLocation(x + paddingLeft - cutLeft + thisPadLeft, y + paddingTop - cutTop);
						}
					}
				}
			}

			for (int y = 0; y < newGrid.GetLength(1); y++) {
				int xLength = newGrid.GetLength(0) - (y & 1);
				for (int x = 0; x < xLength; x++) {
					if (newGrid[x, y] == null) {
						newGrid[x, y] = new HexBase(x, y, this.context, true);
					}
				}
			}
			Vector<Path> paths = this.context.getPaths();
			for (int i = paths.Count - 1; i >= 0; i--) {
				PathNormal p = (PathNormal) paths[i];
				p.shift(direction.SOUTH, paddingTop - cutTop, oddLeftPadding);
				p.shift(direction.EAST, paddingLeft - cutLeft, oddLeftPadding);
			}
			this.context.grid = newGrid;
			this.recalculateScale();
#endif
			}
		}

		private void changeHex(char to)
		{
#if PORT
		if (this.highlightedHex != null) {
			int col = this.highlightedHex[0];
			int row = this.highlightedHex[1];
			if (row >= 0 && row < this.context.gridHeight) {
				if (col >= 0 && col < (this.context.gridWidth - (row & 1))) {
					this.context.grid[col, row].unSetTower();
					switch (to) {
						case 'b':
							this.context.grid[col, row] = new HexBase(col, row, this.context, true);
							this.recalculateScale();
							break;
						case 'e':
						case 'p':
							this.context.grid[col, row] = new HexPath(col, row, this.context);
							this.recalculateScale();
							break;
						case 'n':
							this.context.grid[col, row] = new HexEmpty(col, row, this.context);
							this.recalculateScale();
							break;
					}

				}
			}
		}
#endif
		}

		private void mouseClicked(int button, int screenx, int screeny)
		{
#if PORT
		int[] hexC = this.gameBoard.hexCoordsFromScreenCoords(screenx, screeny);
		int col = hexC[0];
		int row = hexC[1];
		Hex hex;
		bool keepPlacing = false;
		this.panelTowerInfo.unselectTower();
		if (this.context.gameState == gameState.playing) {
			this.panelTowerInfo.setExternalText(this.getStatusMessage());
		}
		this.unHighLighHex();
		if (row >= 0 && row < this.context.gridHeight) {
			if (col >= 0 && col < (this.context.gridWidth - (row & 1))) {
				hex = this.context.grid[col, row];
				if (this.context.gameState == HexTD.gameState.editing) {
					this.jPanelPathEditor.hexClicked(hex);
				} else {
					if (this.placingTower) {
						switch (button) {
							case MouseEvent.BUTTON1:
								this.blackBoxRecord.newTower(col, row, this.placingTowerType);
								this.placingTower = false;
								this.jPanelTowerSelector.stopPlacing();
								break;
							case MouseEvent.BUTTON3:
								this.blackBoxRecord.newTower(col, row, this.placingTowerType);
								keepPlacing = true;
								break;
							case MouseEvent.BUTTON2:
								this.blackBoxRecord.newTower(col, row, this.placingTowerType);
								Tower newTower = hex.getTower();
								if (newTower != null) {
									while (newTower.canUpgrade() && this.context.canPay(newTower.getUpgradePrice())) {
										this.context.blackBoxCurrent.upgradeTower(hexC[0], hexC[1]);
									}
								}
								keepPlacing = true;
								break;
						}
					}

					if (hex.hasTower()) {
						this.panelTowerInfo.setTower(this.context.grid[col, row].getTower());
						this.highLightHex(hex, Hex.highlightType.selectTower);
					} else {
						EnemySprite es = this.context.findClosestCreep(screenx, screeny, context.paintScale);
						if (es != null) {
							this.panelTowerInfo.setCreep(es);
						} else {
							this.panelTowerInfo.unselectCreep();
						}
					}
				}
				return;
			}
		}
		if (this.placingTower && !keepPlacing) {
			this.placingTower = false;
			this.jPanelTowerSelector.stopPlacing();
			this.unHighLighHex();
		}
#endif
		}

		public void keyTyped(char key)
		{
#if PORT
		System.Diagnostics.Debug.WriteLine("HexTD::keyTyped: " + key);
		switch (this.context.gameState) {
			case editing:
				switch (key) {
					case 'b':
					case 'e':
					case 'p':
					case 'n':
						this.changeHex(key);
						break;
				}
				break;
			case playing:
				switch (key) {
					case 'f':
						this.toggleGameSpeed();
						break;
					case 'n':
						this.panelTowerInfo.cancelSell();
						break;
					case 'p':
						this.togglePause();
						break;
					case 'r':
						this.panelTowerInfo.nextMode(2);
						break;
					case 's':
						this.panelTowerInfo.startSellCurrentTower();
						break;
					case 't':
						this.panelTowerInfo.nextMode(1);
						break;
					case 'u':
						this.panelTowerInfo.upgradeCurrentTower(false);
						break;
					case 'U':
						this.panelTowerInfo.upgradeCurrentTower(true);
						break;
					case 'w':
						this.nextWave();
						break;
					case 'y':
						this.panelTowerInfo.confirmSell();
						break;
					case '':
						if (this.placingTower) {
							this.placingTower = false;
							this.jPanelTowerSelector.stopPlacing();
							this.unHighLighHex();
						}
						break;
				}
				break;
			case replaying:
			case checking:
				switch (key) {
					case 'p':
						this.togglePause();
						break;
					case 'f':
						this.toggleGameSpeed();
						break;
				}
				break;
			case selecing:
				switch (key) {
				}
				break;
		}
#endif
		}

		public void showAlert(String alert)
		{
#if PORT
		JOptionPane.showMessageDialog(this,
				alert,
				"Alert!",
				JOptionPane.WARNING_MESSAGE);
#endif
		}

		public void goToReplayCentre()
		{
#if PORT
		this.setPause(true);

		this.context.gameState = gameState.replaying;
		this.blackBoxPlayback.copyFrom(this.blackBoxRecord);

		this.setUI();
#endif
		}

		private void postScore()
		{
#if PORT
		this.jButton_postScore.setEnabled(false);
		String userName = this.jTextField_postUserName.getText();
		if (userName.equals("YourName")) {
			this.jLabel_submitFeedback.setText("Give your name first!");
			this.jButton_postScore.setEnabled(true);
		} else {
			this.jLabel_submitFeedback.setText("");
			try {
				URLConnection connection = this.scorePostUrl.openConnection();
				connection.setDoOutput(true);
				OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
				out.write(URLEncoder.encode("username", "UTF-8") + "=" + URLEncoder.encode(userName, "UTF-8") + "&");
				out.write(URLEncoder.encode("level", "UTF-8") + "=" + URLEncoder.encode("" + this.context.getWave(), "UTF-8") + "&");
				out.write(URLEncoder.encode("score", "UTF-8") + "=" + URLEncoder.encode("" + this.context.getScore(), "UTF-8") + "&");
				out.write(URLEncoder.encode("mapMD5", "UTF-8") + "=" + URLEncoder.encode(this.context.mapMD5, "UTF-8") + "&");
				out.write(URLEncoder.encode("replay", "UTF-8") + "=" + URLEncoder.encode(this.blackBoxRecord.printLog().toString(), "UTF-8") + "&");
				if (this.jCheckBox_replayPublic.isSelected()) {
					out.write(URLEncoder.encode("public", "UTF-8") + "=" + URLEncoder.encode("yes", "UTF-8") + "&");
				} else {
					out.write(URLEncoder.encode("public", "UTF-8") + "=" + URLEncoder.encode("no", "UTF-8") + "&");
				}

				out.close();
				StringBuilder result = new StringBuilder();
				BufferedReader in = new BufferedReader(
						new InputStreamReader(
						connection.getInputStream()));

				String decodedString;

				while ((decodedString = in.readLine()) != null) {
					System.Diagnostics.Debug.WriteLine(decodedString);
					result.append(decodedString);
				}
				in.close();
				int success = result.indexOf("postscore::Success");
				System.Diagnostics.Debug.WriteLine("HexTD::postScore: success = " + success);
				if (success >= 0) {
					this.jLabel_submitFeedback.setText("Score submitted succesfully");
				} else {
					this.jButton_postScore.setEnabled(true);
					this.jLabel_submitFeedback.setText("Failed to submit score!");
				}
			} catch (IOException ex) {
				Logger.getLogger(HexTD.class.getName()).log(Level.SEVERE, null, ex);
			}
		}
#endif
		}

		private void postCheck()
		{
#if PORT
		this.jButton_postReview.setEnabled(false);
		try {
			URLConnection connection = this.scorePostUrl.openConnection();
			connection.setDoOutput(true);
			OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
			out.write(URLEncoder.encode("score_id", "UTF-8") + "=" + URLEncoder.encode("" + this.score_id, "UTF-8") + "&");
			out.write(URLEncoder.encode("level", "UTF-8") + "=" + URLEncoder.encode("" + this.context.getWave(), "UTF-8") + "&");
			out.write(URLEncoder.encode("score", "UTF-8") + "=" + URLEncoder.encode("" + this.context.getScore(), "UTF-8") + "&");

			out.close();
			StringBuilder result = new StringBuilder();
			BufferedReader in = new BufferedReader(
					new InputStreamReader(
					connection.getInputStream()));

			String decodedString;

			while ((decodedString = in.readLine()) != null) {
				System.Diagnostics.Debug.WriteLine(decodedString);
				result.append(decodedString);
			}
			in.close();
			int success = result.indexOf("postscore::Success");
			System.Diagnostics.Debug.WriteLine("HexTD::postCheck: success = " + success);
			if (success >= 0) {
				this.jLabel_submitFeedback1.setText("Check submitted succesfully");
			} else {
				this.jButton_postScore.setEnabled(true);
				this.jLabel_submitFeedback1.setText("Failed to submit check!");
			}
		} catch (IOException ex) {
			Logger.getLogger(HexTD.class.getName()).log(Level.SEVERE, null, ex);
		}
		this.jButton_postReview.setEnabled(true);
#endif
		}

		private TextReader loadReplay(string fetchUrl)
		{
#if PORT

		BufferedReader bufferedreader;
		try {
			System.Diagnostics.Debug.WriteLine("HexTD::loadReplay: File = " + fetchUrl.toString());
			URLConnection urlconnection = fetchUrl.openConnection();
			System.Diagnostics.Debug.WriteLine("HexTD::loadReplay: Encoding: " + urlconnection.getContentEncoding());
			if (urlconnection.getContentEncoding() != null) {
				bufferedreader = new BufferedReader(new InputStreamReader(urlconnection.getInputStream(), urlconnection.getContentEncoding()));
			} else {
				bufferedreader = new BufferedReader(new InputStreamReader(urlconnection.getInputStream(), "utf-8"));
			}
			return bufferedreader;
		} catch (IOException _ex) {
			System.Diagnostics.Debug.WriteLine("HexTD::loadReplay:: IOException while reading from " + fetchUrl);
		}
		System.Diagnostics.Debug.WriteLine("HexTD::loadReplay:: Unknown problem while reading from " + fetchUrl);
		return null;
#else
			return null;
#endif
		}

		public void run()
		{
			long oldTime, newTime, sleepTime;
			oldTime = DateTime.Now.ToUnixMilliseconds();
			int time;
			bool stillPainting;
			lock (this.context.gameTimeLock)
			{
				this.context.gameTime = 0;
			}
			// run a long while (true) this means in our case "always"
			while (this.running)
			{
				lock (this.paintTimeLock)
				{
					this.paintTime++;
				}

#if PORT_FEAT
			if (this.context.gameState == gameState.replaying || this.context.gameState == gameState.checking) {
				if (this.context.gameTime == this.blackBoxPlayback.getNextActionTime()) {
					lock (this.context.gameTimeLock) {
						this.blackBoxPlayback.doActions();
					}
				}
			}
#endif

				if (!this.paused && !this.gameStopped)
				{
					lock (this.context.gameTimeLock)
					{
						if (this.context.isWaveActive() || this.graceTicks-- > 0)
						{
							time = ++this.context.gameTime;
							// Run a gametick
							this.doTick(time);
						}
						else if (this.graceTicks < -1)
						{
							if (this.startWaveDelayed)
							{
								System.Diagnostics.Debug.WriteLine("HexTD::Run: Sync error: Gracetime ran out. Wave started anyway!");
								this.nextWave();
							}
						}
					}

					Dispatcher.BeginInvoke(delegate()
					{
						this.DebugTextBlock.Text = this.context.gameTime.ToString();
					});
				}

				lock (this.paintLock)
				{
					stillPainting = this.painting;
				}
				if (!stillPainting && !this.noPaint)
				{
					// or with Anonymous Delegate
					Dispatcher.BeginInvoke(delegate()
					{
						this.gameBoard.paint(GameBoardCanvas);
					});
				}

				newTime = DateTime.Now.ToUnixMilliseconds();
				sleepTime = oldTime + this.tickTime - newTime;
				oldTime = oldTime + this.tickTime;
				try
				{
					// Stop thread for 20 milliseconds
					// lower ThreadPriority
					//Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
					Thread.Sleep((int)sleepTime);
					// set ThreadPriority to maximum value
					//Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
				}
				catch /* (ArgumentOutOfRangeException ex) */
				{
					// do nothing
				}
			}
			System.Diagnostics.Debug.WriteLine("HexTD::run: GameLogicThread stopping.");
		}

		public void start()
		{
			System.Diagnostics.Debug.WriteLine("HexTD::start: Starting.");
			this.running = true;
		}

		public void stop()
		{
			System.Diagnostics.Debug.WriteLine("HexTD::stop: Stopping.");
			this.running = false;
#if PORT
		this.gameLogicThread.interrupt();
#endif
		}

		public void destroy()
		{
			this.gameLogicThread = null;
#if PORT_FEAT
		this.layer0 = null;
		this.layer1 = null;
		this.blackBoxPlayback = null;
		this.blackBoxRecord = null;
#endif
			this.context = null;
			System.Diagnostics.Debug.WriteLine("HexTD::destroy: Exiting.");
		}

		private void switchExternal(bool external)
		{
#if PORT
		if (external) {
			this.Remove(this.jPanel_gamePanel);
			this.Add(this.jPanel_externalMessage);
			this.jFrame_fullscreen.Add(this.jPanel_gamePanel);
			this.jFrame_fullscreen.setVisible(true);
			this.recalculateScale();
			this.invalidate();
			this.validate();
			this.repaint();
		} else {
			this.Remove(this.jPanel_externalMessage);
			this.Add(this.jPanel_gamePanel);
			this.jFrame_fullscreen.Remove(this.jPanel_gamePanel);
			this.jFrame_fullscreen.setVisible(false);
			this.invalidate();
			this.validate();
			this.repaint();
			this.recalculateScale();
		}
#endif
		}
		/** This method is called from within the init() method to
		 * initialize the form.
		 * WARNING: Do NOT modify this code. The content of this method is
		 * always regenerated by the Form Editor.
		 */
		// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
		private void initComponents()
		{
#if PORT
        java.awt.GridBagConstraints gridBagConstraints;

        colors = new hextd.util.colorSelection();
        jFrame1 = new javax.swing.JFrame();
        jScrollPane2 = new javax.swing.JScrollPane();
        jTextPane_output = new javax.swing.JTextPane();
        jPopupMenu = new javax.swing.JPopupMenu();
        jMenuItem_restartLevel = new javax.swing.JMenuItem();
        jMenuItem_exitLevel = new javax.swing.JMenuItem();
        jMenuItem_editLevel = new javax.swing.JMenuItem();
        jMenuItem_ReplayCenter = new javax.swing.JMenuItem();
        jCheckBoxMenuItem_background = new javax.swing.JCheckBoxMenuItem();
        jCheckBoxMenuItem_external = new javax.swing.JCheckBoxMenuItem();
        jFrame_fullscreen = new javax.swing.JFrame();
        jPanel_externalMessage = new javax.swing.JPanel();
        jButton3 = new javax.swing.JButton();
        jLabel7 = new javax.swing.JLabel();
        jLabel19 = new javax.swing.JLabel();
        jLabel20 = new javax.swing.JLabel();
        jPanel_gamePanel = new javax.swing.JPanel();
        jPanel_gameButtons = new javax.swing.JPanel();
        jButton_nextWave = new javax.swing.JButton();
        jCheckBox_autoLaunch = new javax.swing.JCheckBox();
        jButton_menu = new javax.swing.JButton();
        jLabel_gameTitle = new javax.swing.JLabel();
        jLabel10 = new javax.swing.JLabel();
        jCheckBox_fastForward = new javax.swing.JCheckBox();
        jLabel_debug = new javax.swing.JLabel();
        jPanel_board = new javax.swing.JPanel();
        jPanel_GameLost = new javax.swing.JPanel();
        jLabel11 = new javax.swing.JLabel();
        jButton_lostTryAgain = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jPanel_GameWon = new javax.swing.JPanel();
        jLabel12 = new javax.swing.JLabel();
        jButton_wonTryAgain = new javax.swing.JButton();
        jButton1 = new javax.swing.JButton();
        jPanel_replayEnded = new javax.swing.JPanel();
        jLabel21 = new javax.swing.JLabel();
        jPanel_submitScore = new javax.swing.JPanel();
        jTextField_postUserName = new javax.swing.JTextField();
        jLabel22 = new javax.swing.JLabel();
        jButton_postScore = new javax.swing.JButton();
        jLabel_submitFeedback = new javax.swing.JLabel();
        jCheckBox_replayPublic = new javax.swing.JCheckBox();
        jPanel_submitReview = new javax.swing.JPanel();
        jLabel23 = new javax.swing.JLabel();
        jButton_postReview = new javax.swing.JButton();
        jLabel_submitFeedback1 = new javax.swing.JLabel();
        jPanel_console = new javax.swing.JPanel();
        panelWaveInfo = new hextd.UI.PanelWaveInfo();
        panelTowerInfo = new hextd.UI.PanelTowerInfo();
        jPanel_gameInfo = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jLabel_wave = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel_credits = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        jLabel_lives = new javax.swing.JLabel();
        jLabel8 = new javax.swing.JLabel();
        jLabel_interest = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jLabel_bonus = new javax.swing.JLabel();
        jLabel9 = new javax.swing.JLabel();
        jLabel_score = new javax.swing.JLabel();
        jPanel_editor = new javax.swing.JPanel();
        jLabel2 = new javax.swing.JLabel();
        jSpinner_width = new javax.swing.JSpinner();
        jSpinner_height = new javax.swing.JSpinner();
        jLabel4 = new javax.swing.JLabel();
        jCheckBox_addTop = new javax.swing.JCheckBox();
        jCheckBox_addLeft = new javax.swing.JCheckBox();
        jButton_printMap = new javax.swing.JButton();
        jLabel13 = new javax.swing.JLabel();
        jLabel14 = new javax.swing.JLabel();
        jSpinner_interestStart = new javax.swing.JSpinner();
        jSpinner_interestIncrease = new javax.swing.JSpinner();
        jLabel15 = new javax.swing.JLabel();
        jSpinner_moneyStart = new javax.swing.JSpinner();
        jLabel16 = new javax.swing.JLabel();
        jSpinner_lives = new javax.swing.JSpinner();
        jLabel17 = new javax.swing.JLabel();
        jTextField_background = new javax.swing.JTextField();
        jLabel18 = new javax.swing.JLabel();
        jTextField_title = new javax.swing.JTextField();
        jPanelPathEditor = new hextd.UI.PanelPathEditor();
        jPanelTowerSelector = new hextd.UI.PanelTowerSelector();
        jPanelLevelSelector = new hextd.UI.PanelLevelSelector();
        panelReplayControls = new hextd.UI.PanelReplayControls();

#endif
			colors.setColorBaseBackGround(Color.FromArgb(255, 0, 0, 0));
			colors.setColorBaseEmptyHexBorder(Color.FromArgb(255, 56, 149, 185));
			colors.setColorBaseHexBackGround(Color.FromArgb(255, 33, 54, 75));
			colors.setColorBaseHexBorder(Color.FromArgb(255, 183, 183, 244));
			colors.setColorForeGround(Color.FromArgb(255, 220, 255, 220));
			colors.setColorHealthLine(Color.FromArgb(255, 0, 199, 0));
			colors.setColorHighlightNOK(Color.FromArgb(255, 255, 0, 0));
			colors.setColorHighlightOK(Color.FromArgb(255, 213, 255, 213));
			colors.setColorOpenBackGround(Color.FromArgb(255, 50, 0, 25));
			colors.setColorRangeCircle(Color.FromArgb(255, 204, 204, 204));

#if PORT
        jFrame1.getContentPane().setLayout(new java.awt.GridBagLayout());

        jScrollPane2.setMinimumSize(new java.awt.Dimension(200, 200));
        jScrollPane2.setPreferredSize(new java.awt.Dimension(200, 200));
        jScrollPane2.setViewportView(jTextPane_output);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 0.01;
        gridBagConstraints.weighty = 0.01;
        jFrame1.getContentPane().Add(jScrollPane2, gridBagConstraints);

        jPopupMenu.setBackground(colors.getColorBackGround());
        jPopupMenu.setForeground(colors.getColorForeGround());

        jMenuItem_restartLevel.setBackground(colors.getColorBackGround());
        jMenuItem_restartLevel.setForeground(colors.getColorForeGround());
        jMenuItem_restartLevel.setText("Restart Level");
        jMenuItem_restartLevel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem_restartLevelActionPerformed(evt);
            }
        });
        jPopupMenu.Add(jMenuItem_restartLevel);

        jMenuItem_exitLevel.setBackground(colors.getColorBackGround());
        jMenuItem_exitLevel.setForeground(colors.getColorForeGround());
        jMenuItem_exitLevel.setText("Level Selection");
        jMenuItem_exitLevel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem_exitLevelActionPerformed(evt);
            }
        });
        jPopupMenu.Add(jMenuItem_exitLevel);

        jMenuItem_editLevel.setBackground(colors.getColorBackGround());
        jMenuItem_editLevel.setForeground(colors.getColorForeGround());
        jMenuItem_editLevel.setText("Level Editor");
        jMenuItem_editLevel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem_editLevelActionPerformed(evt);
            }
        });
        jPopupMenu.Add(jMenuItem_editLevel);

        jMenuItem_ReplayCenter.setBackground(colors.getColorBackGround());
        jMenuItem_ReplayCenter.setForeground(colors.getColorForeGround());
        jMenuItem_ReplayCenter.setText("Replay Centre");
        jMenuItem_ReplayCenter.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem_ReplayCenterActionPerformed(evt);
            }
        });
        jPopupMenu.Add(jMenuItem_ReplayCenter);

        jCheckBoxMenuItem_background.setBackground(colors.getColorBackGround());
        jCheckBoxMenuItem_background.setForeground(colors.getColorForeGround());
        jCheckBoxMenuItem_background.setSelected(true);
        jCheckBoxMenuItem_background.setText("Background");
        jCheckBoxMenuItem_background.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jCheckBoxMenuItem_backgroundStateChanged(evt);
            }
        });
        jPopupMenu.Add(jCheckBoxMenuItem_background);

        jCheckBoxMenuItem_external.setBackground(colors.getColorBackGround());
        jCheckBoxMenuItem_external.setForeground(colors.getColorForeGround());
        jCheckBoxMenuItem_external.setText("Escape from Browser");
        jCheckBoxMenuItem_external.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBoxMenuItem_externalActionPerformed(evt);
            }
        });
        jPopupMenu.Add(jCheckBoxMenuItem_external);

        jFrame_fullscreen.setMinimumSize(new java.awt.Dimension(400, 350));

        jPanel_externalMessage.setBackground(colors.getColorBackGround());
        jPanel_externalMessage.setForeground(colors.getColorForeGround());
        jPanel_externalMessage.setLayout(new java.awt.GridBagLayout());

        jButton3.setBackground(colors.getColorBackGround());
        jButton3.setForeground(colors.getColorForeGround());
        jButton3.setText("Recover Game");
        jButton3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton3ActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        jPanel_externalMessage.Add(jButton3, gridBagConstraints);

        jLabel7.setBackground(colors.getColorBackGround());
        jLabel7.setForeground(colors.getColorForeGround());
        jLabel7.setText("The game is currently running in external mode.");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        jPanel_externalMessage.Add(jLabel7, gridBagConstraints);

        jLabel19.setBackground(colors.getColorBackGround());
        jLabel19.setForeground(colors.getColorForeGround());
        jLabel19.setText("Navigating away from this page will quit the game!");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        jPanel_externalMessage.Add(jLabel19, gridBagConstraints);

        jLabel20.setBackground(colors.getColorBackGround());
        jLabel20.setForeground(colors.getColorForeGround());
        jLabel20.setText("Click the button to move the game back to this window.");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        jPanel_externalMessage.Add(jLabel20, gridBagConstraints);

        addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentResized(java.awt.event.ComponentEvent evt) {
                formComponentResized(evt);
            }
        });

        jPanel_gamePanel.setBackground(colors.getColorBackGround());
        jPanel_gamePanel.setForeground(colors.getColorForeGround());
        jPanel_gamePanel.setLayout(new java.awt.GridBagLayout());

        jPanel_gameButtons.setBackground(colors.getColorBackGround());
        jPanel_gameButtons.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        jPanel_gameButtons.setForeground(colors.getColorForeGround());
        jPanel_gameButtons.setFocusable(false);
        jPanel_gameButtons.setLayout(new java.awt.GridBagLayout());

        jButton_nextWave.setBackground(colors.getColorBackGround());
        jButton_nextWave.setForeground(colors.getColorForeGround());
        jButton_nextWave.setText("Next Wave");
        jButton_nextWave.setFocusable(false);
        jButton_nextWave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton_nextWaveActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridheight = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
        gridBagConstraints.weightx = 0.1;
        gridBagConstraints.insets = new java.awt.Insets(2, 5, 2, 5);
        jPanel_gameButtons.Add(jButton_nextWave, gridBagConstraints);

        jCheckBox_autoLaunch.setBackground(colors.getColorBackGround());
        jCheckBox_autoLaunch.setForeground(colors.getColorForeGround());
        jCheckBox_autoLaunch.setText("Auto Launch");
        jCheckBox_autoLaunch.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        jCheckBox_autoLaunch.setFocusable(false);
        jCheckBox_autoLaunch.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jCheckBox_autoLaunchStateChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 4;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5);
        jPanel_gameButtons.Add(jCheckBox_autoLaunch, gridBagConstraints);

        jButton_menu.setBackground(colors.getColorBackGround());
        jButton_menu.setForeground(colors.getColorForeGround());
        jButton_menu.setText("Menu");
        jButton_menu.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                jButton_menuMousePressed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridheight = 2;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 0);
        jPanel_gameButtons.Add(jButton_menu, gridBagConstraints);

        jLabel_gameTitle.setBackground(colors.getColorBackGround());
        jLabel_gameTitle.setFont(new java.awt.Font("Dialog", 1, 16));
        jLabel_gameTitle.setForeground(colors.getColorForeGround());
        jLabel_gameTitle.setText(this.NAME);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridheight = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTH;
        gridBagConstraints.insets = new java.awt.Insets(0, 10, 4, 10);
        jPanel_gameButtons.Add(jLabel_gameTitle, gridBagConstraints);

        jLabel10.setBackground(colors.getColorBackGround());
        jLabel10.setFont(new java.awt.Font("Dialog", 0, 10));
        jLabel10.setForeground(colors.getColorForeGround());
        jLabel10.setText("v"+this.VERSION);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTH;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 4, 0);
        jPanel_gameButtons.Add(jLabel10, gridBagConstraints);

        jCheckBox_fastForward.setBackground(colors.getColorBackGround());
        jCheckBox_fastForward.setForeground(colors.getColorForeGround());
        jCheckBox_fastForward.setText("Fast Mode");
        jCheckBox_fastForward.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        jCheckBox_fastForward.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jCheckBox_fastForwardStateChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 4;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5);
        jPanel_gameButtons.Add(jCheckBox_fastForward, gridBagConstraints);

        jLabel_debug.setBackground(colors.getColorBackGround());
        jLabel_debug.setFont(new java.awt.Font("Dialog", 0, 10));
        jLabel_debug.setForeground(colors.getColorForeGround());
        jLabel_debug.setText("debug");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        jPanel_gameButtons.Add(jLabel_debug, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
        gridBagConstraints.weightx = 0.01;
        jPanel_gamePanel.Add(jPanel_gameButtons, gridBagConstraints);

        jPanel_board.setBackground(colors.getColorBackGround());
        jPanel_board.setForeground(colors.getColorForeGround());
        jPanel_board.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jPanel_boardMouseClicked(evt);
            }
        });
        jPanel_board.addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentResized(java.awt.event.ComponentEvent evt) {
                jPanel_boardComponentResized(evt);
            }
        });
        jPanel_board.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseMoved(java.awt.event.MouseEvent evt) {
                jPanel_boardMouseMoved(evt);
            }
        });
        jPanel_board.setLayout(new java.awt.GridBagLayout());

        jPanel_GameLost.setBackground(colors.getColorBackGround());
        jPanel_GameLost.setForeground(colors.getColorForeGround());
        jPanel_GameLost.setLayout(new java.awt.GridBagLayout());

        jLabel11.setBackground(colors.getColorBackGround());
        jLabel11.setFont(new java.awt.Font("SansSerif", 1, 18));
        jLabel11.setForeground(colors.getColorForeGround());
        jLabel11.setText("Game Over!");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        jPanel_GameLost.Add(jLabel11, gridBagConstraints);

        jButton_lostTryAgain.setBackground(colors.getColorBackGround());
        jButton_lostTryAgain.setForeground(colors.getColorForeGround());
        jButton_lostTryAgain.setText("Try Again");
        jButton_lostTryAgain.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton_lostTryAgainActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        jPanel_GameLost.Add(jButton_lostTryAgain, gridBagConstraints);

        jButton2.setBackground(colors.getColorBackGround());
        jButton2.setForeground(colors.getColorForeGround());
        jButton2.setText("Watch Replay");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        jPanel_GameLost.Add(jButton2, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 0.1;
        gridBagConstraints.weighty = 0.1;
        jPanel_board.Add(jPanel_GameLost, gridBagConstraints);

        jPanel_GameWon.setBackground(colors.getColorBackGround());
        jPanel_GameWon.setForeground(colors.getColorForeGround());
        jPanel_GameWon.setLayout(new java.awt.GridBagLayout());

        jLabel12.setBackground(colors.getColorBackGround());
        jLabel12.setFont(new java.awt.Font("SansSerif", 1, 18));
        jLabel12.setForeground(colors.getColorForeGround());
        jLabel12.setText("Congratulations!");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        jPanel_GameWon.Add(jLabel12, gridBagConstraints);

        jButton_wonTryAgain.setBackground(colors.getColorBackGround());
        jButton_wonTryAgain.setForeground(colors.getColorForeGround());
        jButton_wonTryAgain.setText("Try Again");
        jButton_wonTryAgain.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton_wonTryAgainActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        jPanel_GameWon.Add(jButton_wonTryAgain, gridBagConstraints);

        jButton1.setBackground(colors.getColorBackGround());
        jButton1.setForeground(colors.getColorForeGround());
        jButton1.setText("Watch Replay");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        jPanel_GameWon.Add(jButton1, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 0.1;
        gridBagConstraints.weighty = 0.1;
        jPanel_board.Add(jPanel_GameWon, gridBagConstraints);

        jPanel_replayEnded.setBackground(colors.getColorBackGround());
        jPanel_replayEnded.setForeground(colors.getColorForeGround());
        jPanel_replayEnded.setLayout(new java.awt.GridBagLayout());

        jLabel21.setBackground(colors.getColorBackGround());
        jLabel21.setFont(new java.awt.Font("SansSerif", 1, 18));
        jLabel21.setForeground(colors.getColorForeGround());
        jLabel21.setText("Replay Ended");
        jPanel_replayEnded.add(jLabel21, new java.awt.GridBagConstraints());

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 0.1;
        gridBagConstraints.weighty = 0.1;
        jPanel_board.Add(jPanel_replayEnded, gridBagConstraints);

        jPanel_submitScore.setBackground(colors.getColorBackGround());
        jPanel_submitScore.setForeground(colors.getColorForeGround());
        jPanel_submitScore.setLayout(new java.awt.GridBagLayout());

        jTextField_postUserName.setBackground(colors.getColorBackGround());
        jTextField_postUserName.setColumns(15);
        jTextField_postUserName.setForeground(colors.getColorForeGround());
        jTextField_postUserName.setText("YourName");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
        jPanel_submitScore.Add(jTextField_postUserName, gridBagConstraints);

        jLabel22.setBackground(colors.getColorBackGround());
        jLabel22.setForeground(colors.getColorForeGround());
        jLabel22.setText("Submit Score:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
        jPanel_submitScore.Add(jLabel22, gridBagConstraints);

        jButton_postScore.setBackground(colors.getColorBackGround());
        jButton_postScore.setForeground(colors.getColorForeGround());
        jButton_postScore.setText("Submit");
        jButton_postScore.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton_postScoreActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
        jPanel_submitScore.Add(jButton_postScore, gridBagConstraints);

        jLabel_submitFeedback.setBackground(colors.getColorBackGround());
        jLabel_submitFeedback.setForeground(colors.getColorForeGround());
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
        gridBagConstraints.weighty = 1.0E-4;
        jPanel_submitScore.Add(jLabel_submitFeedback, gridBagConstraints);

        jCheckBox_replayPublic.setBackground(colors.getColorBackGround());
        jCheckBox_replayPublic.setForeground(colors.getColorForeGround());
        jCheckBox_replayPublic.setText("Public: Allow everyone to watch the replay.");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.gridwidth = 2;
        jPanel_submitScore.Add(jCheckBox_replayPublic, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 0.1;
        gridBagConstraints.weighty = 0.1;
        jPanel_board.Add(jPanel_submitScore, gridBagConstraints);

        jPanel_submitReview.setBackground(colors.getColorBackGround());
        jPanel_submitReview.setForeground(colors.getColorForeGround());
        jPanel_submitReview.setLayout(new java.awt.GridBagLayout());

        jLabel23.setBackground(colors.getColorBackGround());
        jLabel23.setForeground(colors.getColorForeGround());
        jLabel23.setText("Submit Review");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
        jPanel_submitReview.Add(jLabel23, gridBagConstraints);

        jButton_postReview.setBackground(colors.getColorBackGround());
        jButton_postReview.setForeground(colors.getColorForeGround());
        jButton_postReview.setText("Submit");
        jButton_postReview.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton_postReviewActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
        jPanel_submitReview.Add(jButton_postReview, gridBagConstraints);

        jLabel_submitFeedback1.setBackground(colors.getColorBackGround());
        jLabel_submitFeedback1.setForeground(colors.getColorForeGround());
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
        gridBagConstraints.weighty = 1.0E-4;
        jPanel_submitReview.Add(jLabel_submitFeedback1, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 0.1;
        gridBagConstraints.weighty = 0.1;
        jPanel_board.Add(jPanel_submitReview, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 0.1;
        gridBagConstraints.weighty = 0.1;
        jPanel_gamePanel.Add(jPanel_board, gridBagConstraints);

        jPanel_console.setBackground(colors.getColorBackGround());
        jPanel_console.setForeground(colors.getColorForeGround());
        jPanel_console.setFocusable(false);
        jPanel_console.setMaximumSize(new java.awt.Dimension(200, 2147483647));
        jPanel_console.setMinimumSize(new java.awt.Dimension(200, 263));
        jPanel_console.setPreferredSize(new java.awt.Dimension(200, 402));
        jPanel_console.setLayout(new java.awt.GridBagLayout());

        panelWaveInfo.setBackground(colors.getColorBackGround());
        panelWaveInfo.setForeground(colors.getColorForeGround());
        panelWaveInfo.setMinimumSize(null);
        panelWaveInfo.setName("Current Wave:"); // NOI18N
        panelWaveInfo.setPreferredSize(null);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 8;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTH;
        gridBagConstraints.weightx = 0.01;
        gridBagConstraints.weighty = 0.2;
        jPanel_console.Add(panelWaveInfo, gridBagConstraints);

        panelTowerInfo.setBackground(colors.getColorBackGround());
        panelTowerInfo.setForeground(colors.getColorForeGround());
        panelTowerInfo.setFocusable(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 6;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
        gridBagConstraints.weightx = 0.01;
        gridBagConstraints.weighty = 0.1;
        jPanel_console.Add(panelTowerInfo, gridBagConstraints);

        jPanel_gameInfo.setBackground(colors.getColorBackGround());
        jPanel_gameInfo.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Status", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Bitstream Vera Sans", 0, 13), colors.getColorForeGround()));
        jPanel_gameInfo.setForeground(colors.getColorForeGround());
        jPanel_gameInfo.setFocusable(false);
        jPanel_gameInfo.setLayout(new java.awt.GridBagLayout());

        jLabel1.setBackground(colors.getColorBackGround());
        jLabel1.setForeground(colors.getColorForeGround());
        jLabel1.setText("Wave:");
        jLabel1.setFocusable(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_gameInfo.Add(jLabel1, gridBagConstraints);

        jLabel_wave.setBackground(colors.getColorBackGround());
        jLabel_wave.setForeground(colors.getColorForeGround());
        jLabel_wave.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel_wave.setText("xx/xx");
        jLabel_wave.setFocusable(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_gameInfo.Add(jLabel_wave, gridBagConstraints);

        jLabel3.setBackground(colors.getColorBackGround());
        jLabel3.setForeground(colors.getColorForeGround());
        jLabel3.setText("Cash:");
        jLabel3.setFocusable(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_gameInfo.Add(jLabel3, gridBagConstraints);

        jLabel_credits.setBackground(colors.getColorBackGround());
        jLabel_credits.setForeground(colors.getColorForeGround());
        jLabel_credits.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel_credits.setText("000000");
        jLabel_credits.setFocusable(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 0);
        jPanel_gameInfo.Add(jLabel_credits, gridBagConstraints);

        jLabel6.setBackground(colors.getColorBackGround());
        jLabel6.setForeground(colors.getColorForeGround());
        jLabel6.setText("Lives:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_gameInfo.Add(jLabel6, gridBagConstraints);

        jLabel_lives.setBackground(colors.getColorBackGround());
        jLabel_lives.setForeground(colors.getColorForeGround());
        jLabel_lives.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel_lives.setText("xx");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_gameInfo.Add(jLabel_lives, gridBagConstraints);

        jLabel8.setBackground(colors.getColorBackGround());
        jLabel8.setForeground(colors.getColorForeGround());
        jLabel8.setText("Interest:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_gameInfo.Add(jLabel8, gridBagConstraints);

        jLabel_interest.setBackground(colors.getColorBackGround());
        jLabel_interest.setForeground(colors.getColorForeGround());
        jLabel_interest.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel_interest.setText("x%");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_gameInfo.Add(jLabel_interest, gridBagConstraints);

        jLabel5.setBackground(colors.getColorBackGround());
        jLabel5.setForeground(colors.getColorForeGround());
        jLabel5.setText("Bonus:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_gameInfo.Add(jLabel5, gridBagConstraints);

        jLabel_bonus.setBackground(colors.getColorBackGround());
        jLabel_bonus.setForeground(colors.getColorForeGround());
        jLabel_bonus.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel_bonus.setText("0");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_gameInfo.Add(jLabel_bonus, gridBagConstraints);

        jLabel9.setBackground(colors.getColorBackGround());
        jLabel9.setForeground(colors.getColorForeGround());
        jLabel9.setText("Score:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_gameInfo.Add(jLabel9, gridBagConstraints);

        jLabel_score.setBackground(colors.getColorBackGround());
        jLabel_score.setForeground(colors.getColorForeGround());
        jLabel_score.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel_score.setText("0000000");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 0);
        jPanel_gameInfo.Add(jLabel_score, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
        gridBagConstraints.weightx = 0.01;
        jPanel_console.Add(jPanel_gameInfo, gridBagConstraints);

        jPanel_editor.setBackground(colors.getColorBackGround());
        jPanel_editor.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Board Editor", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Bitstream Vera Sans", 0, 13), colors.getColorForeGround()));
        jPanel_editor.setForeground(colors.getColorForeGround());
        jPanel_editor.setFocusable(false);
        jPanel_editor.setLayout(new java.awt.GridBagLayout());

        jLabel2.setBackground(colors.getColorBackGround());
        jLabel2.setForeground(colors.getColorForeGround());
        jLabel2.setText("Width:");
        jLabel2.setFocusable(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_editor.Add(jLabel2, gridBagConstraints);

        jSpinner_width.setBackground(colors.getColorBackGround());
        jSpinner_width.setForeground(colors.getColorForeGround());
        jSpinner_width.setModel(new SpinnerNumberModel(12, 1, 999, 1));
        jSpinner_width.setFocusable(false);
        jSpinner_width.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jSpinner_widthStateChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.weightx = 0.01;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_editor.Add(jSpinner_width, gridBagConstraints);

        jSpinner_height.setBackground(colors.getColorBackGround());
        jSpinner_height.setForeground(colors.getColorForeGround());
        jSpinner_height.setModel(new SpinnerNumberModel(13, 1, 999, 1));
        jSpinner_height.setFocusable(false);
        jSpinner_height.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jSpinner_heightStateChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.weightx = 0.01;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_editor.Add(jSpinner_height, gridBagConstraints);

        jLabel4.setBackground(colors.getColorBackGround());
        jLabel4.setForeground(colors.getColorForeGround());
        jLabel4.setText("Height:");
        jLabel4.setFocusable(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_editor.Add(jLabel4, gridBagConstraints);

        jCheckBox_addTop.setBackground(colors.getColorBackGround());
        jCheckBox_addTop.setForeground(colors.getColorForeGround());
        jCheckBox_addTop.setText("top");
        jCheckBox_addTop.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_editor.Add(jCheckBox_addTop, gridBagConstraints);

        jCheckBox_addLeft.setBackground(colors.getColorBackGround());
        jCheckBox_addLeft.setForeground(colors.getColorForeGround());
        jCheckBox_addLeft.setText("left");
        jCheckBox_addLeft.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_editor.Add(jCheckBox_addLeft, gridBagConstraints);

        jButton_printMap.setBackground(colors.getColorBackGround());
        jButton_printMap.setForeground(colors.getColorForeGround());
        jButton_printMap.setText("print");
        jButton_printMap.setMargin(new java.awt.Insets(2, 2, 2, 2));
        jButton_printMap.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton_printMapActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 4;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_editor.Add(jButton_printMap, gridBagConstraints);

        jLabel13.setBackground(colors.getColorBackGround());
        jLabel13.setForeground(colors.getColorForeGround());
        jLabel13.setText("Start Interest:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.gridwidth = 4;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_editor.Add(jLabel13, gridBagConstraints);

        jLabel14.setBackground(colors.getColorBackGround());
        jLabel14.setForeground(colors.getColorForeGround());
        jLabel14.setText("Interest Increase:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 5;
        gridBagConstraints.gridwidth = 4;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_editor.Add(jLabel14, gridBagConstraints);

        jSpinner_interestStart.setBackground(colors.getColorBackGround());
        jSpinner_interestStart.setForeground(colors.getColorForeGround());
        jSpinner_interestStart.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jSpinner_interestStartStateChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 4;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_editor.Add(jSpinner_interestStart, gridBagConstraints);

        jSpinner_interestIncrease.setBackground(colors.getColorBackGround());
        jSpinner_interestIncrease.setForeground(colors.getColorForeGround());
        jSpinner_interestIncrease.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jSpinner_interestIncreaseStateChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 4;
        gridBagConstraints.gridy = 5;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_editor.Add(jSpinner_interestIncrease, gridBagConstraints);

        jLabel15.setBackground(colors.getColorBackGround());
        jLabel15.setForeground(colors.getColorForeGround());
        jLabel15.setText("Start Money:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_editor.Add(jLabel15, gridBagConstraints);

        jSpinner_moneyStart.setBackground(colors.getColorBackGround());
        jSpinner_moneyStart.setForeground(colors.getColorForeGround());
        jSpinner_moneyStart.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jSpinner_moneyStartStateChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_editor.Add(jSpinner_moneyStart, gridBagConstraints);

        jLabel16.setBackground(colors.getColorBackGround());
        jLabel16.setForeground(colors.getColorForeGround());
        jLabel16.setText("Start Lives:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 6;
        gridBagConstraints.gridwidth = 4;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_editor.Add(jLabel16, gridBagConstraints);

        jSpinner_lives.setBackground(colors.getColorBackGround());
        jSpinner_lives.setForeground(colors.getColorForeGround());
        jSpinner_lives.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jSpinner_livesStateChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 4;
        gridBagConstraints.gridy = 6;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_editor.Add(jSpinner_lives, gridBagConstraints);

        jLabel17.setBackground(colors.getColorBackGround());
        jLabel17.setForeground(colors.getColorForeGround());
        jLabel17.setText("background:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 7;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_editor.Add(jLabel17, gridBagConstraints);

        jTextField_background.setBackground(colors.getColorBackGround());
        jTextField_background.setForeground(colors.getColorForeGround());
        jTextField_background.setText("jTextField1");
        jTextField_background.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jTextField_backgroundActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 7;
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        jPanel_editor.Add(jTextField_background, gridBagConstraints);

        jLabel18.setBackground(colors.getColorBackGround());
        jLabel18.setForeground(colors.getColorForeGround());
        jLabel18.setText("Title:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 2, 2);
        jPanel_editor.Add(jLabel18, gridBagConstraints);

        jTextField_title.setBackground(colors.getColorBackGround());
        jTextField_title.setForeground(colors.getColorForeGround());
        jTextField_title.setText("jTextField1");
        jTextField_title.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jTextField_titleActionPerformed(evt);
            }
        });
        jTextField_title.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                jTextField_titleKeyReleased(evt);
            }
            public void keyTyped(java.awt.event.KeyEvent evt) {
                jTextField_titleKeyTyped(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = 4;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 2, 2);
        jPanel_editor.Add(jTextField_title, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
        gridBagConstraints.weightx = 0.01;
        jPanel_console.Add(jPanel_editor, gridBagConstraints);

        jPanelPathEditor.setBackground(colors.getColorBackGround());
        jPanelPathEditor.setForeground(colors.getColorForeGround());
        jPanelPathEditor.setMinimumSize(new java.awt.Dimension(200, 150));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
        gridBagConstraints.weightx = 0.01;
        gridBagConstraints.weighty = 0.05;
        jPanel_console.Add(jPanelPathEditor, gridBagConstraints);

        jPanelTowerSelector.setBackground(colors.getColorBackGround());
        jPanelTowerSelector.setForeground(colors.getColorForeGround());
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 0.01;
        jPanel_console.Add(jPanelTowerSelector, gridBagConstraints);

        jPanelLevelSelector.setBackground(colors.getColorBackGround());
        jPanelLevelSelector.setForeground(colors.getColorForeGround());
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 7;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 0.01;
        gridBagConstraints.weighty = 0.01;
        jPanel_console.Add(jPanelLevelSelector, gridBagConstraints);

        panelReplayControls.setBackground(colors.getColorBackGround());
        panelReplayControls.setForeground(colors.getColorForeGround());
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 5;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        jPanel_console.Add(panelReplayControls, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridheight = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL;
        gridBagConstraints.weighty = 1.0;
        jPanel_gamePanel.Add(jPanel_console, gridBagConstraints);

        getContentPane().Add(jPanel_gamePanel, java.awt.BorderLayout.CENTER);
#endif
		}

#if PORT
    private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {                                         
		this.jCheckBoxMenuItem_external.setSelected(false);
		this.switchExternal(this.jCheckBoxMenuItem_external.isSelected());
    }                                        

    private void jCheckBoxMenuItem_externalActionPerformed(java.awt.event.ActionEvent evt) {                                                           
		this.switchExternal(this.jCheckBoxMenuItem_external.isSelected());
    }                                                          

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
		this.goToReplayCentre();
    }                                        

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
		this.goToReplayCentre();
    }                                        

    private void jMenuItem_editLevelActionPerformed(java.awt.event.ActionEvent evt) {                                                    
		context.gameState = HexTD.gameState.editing;
		this.setUI();
    }                                                   

    private void jMenuItem_ReplayCenterActionPerformed(java.awt.event.ActionEvent evt) {                                                       
		this.goToReplayCentre();
    }                                                      

    private void jTextField_titleActionPerformed(java.awt.event.ActionEvent evt) {                                                 
		this.context.levelTitle = this.jTextField_title.getText();
    }                                                

    private void jTextField_backgroundActionPerformed(java.awt.event.ActionEvent evt) {                                                      
		this.context.backgroundImage = this.jTextField_background.getText();
		if (this.context.backgroundImage.length() == 0) {
			this.context.backgroundImage = this.backgroundDefault;
		}
		this.context.clearImages();
		this.clearLayer0 = true;
    }                                                     

    private void jCheckBoxMenuItem_backgroundStateChanged(javax.swing.event.ChangeEvent evt) {                                                          
		this.drawBackground = this.jCheckBoxMenuItem_background.isSelected();
		this.clearLayer0 = true;
    }                                                         

    private void jSpinner_livesStateChanged(javax.swing.event.ChangeEvent evt) {                                            
		try {
			this.context.livesStart = new Integer(this.jSpinner_lives.getValue().toString()).intValue();
		} catch (NumberFormatException ex) {
			ex.printStackTrace();
		}
    }                                           

    private void jMenuItem_restartLevelActionPerformed(java.awt.event.ActionEvent evt) {                                                       
		this.startLevel();
    }                                                      

    private void jButton_wonTryAgainActionPerformed(java.awt.event.ActionEvent evt) {                                                    
		this.startLevel();
    }                                                   

    private void jButton_lostTryAgainActionPerformed(java.awt.event.ActionEvent evt) {                                                     
		this.startLevel();
    }                                                    

    private void jSpinner_moneyStartStateChanged(javax.swing.event.ChangeEvent evt) {                                                 
		try {
			this.context.creditsStart = new Long(this.jSpinner_moneyStart.getValue().toString()).intValue();
		} catch (NumberFormatException ex) {
			ex.printStackTrace();
		}
    }                                                

    private void jSpinner_interestIncreaseStateChanged(javax.swing.event.ChangeEvent evt) {                                                       
		try {
			this.context.interestIncrease = new Integer(this.jSpinner_interestIncrease.getValue().toString()).intValue();
			this.context.setInterest(this.context.interestStart, this.context.interestIncrease);
		} catch (NumberFormatException ex) {
			ex.printStackTrace();
		}
    }                                                      

    private void jSpinner_interestStartStateChanged(javax.swing.event.ChangeEvent evt) {                                                    
		try {
			this.context.interestStart = new Integer(this.jSpinner_interestStart.getValue().toString()).intValue();
			this.context.setInterest(this.context.interestStart, this.context.interestIncrease);
		} catch (NumberFormatException ex) {
			ex.printStackTrace();
		}
    }                                                   

    private void jCheckBox_fastForwardStateChanged(javax.swing.event.ChangeEvent evt) {                                                   
		this.noSleep = this.jCheckBox_fastForward.isSelected();
		synchronized (this.context.gameTimeLock) {
			if (this.noSleep) {
				this.tickTime = 15;
			} else {
				this.tickTime = 50;
			}
		}
}                                                  

    private void jButton_menuMousePressed(java.awt.event.MouseEvent evt) {                                          
		jPopupMenu.show(evt.getComponent(), evt.getX(), evt.getY());
    }                                         

    private void jMenuItem_exitLevelActionPerformed(java.awt.event.ActionEvent evt) {                                                    
		this.gameStopped = false;
		this.context.gameState = HexTD.gameState.selecing;
		jCheckBox_autoLaunch.setSelected(false);
		this.autoLaunch = false;
		this.context.resetWaves();
		this.context.removeAllEnemies();
		this.setUI();
    }                                                   

    private void jButton_printMapActionPerformed(java.awt.event.ActionEvent evt) {                                                 
		this.jTextPane_output.setText(MapIO.printMap(this.context));
		this.jFrame1.setVisible(true);
		this.jFrame1.pack();
    }                                                

    private void jSpinner_heightStateChanged(javax.swing.event.ChangeEvent evt) {                                             
		this.resizeGrid();
    }                                            

    private void jSpinner_widthStateChanged(javax.swing.event.ChangeEvent evt) {                                            
		this.resizeGrid();
    }                                           

    private void jCheckBox_autoLaunchStateChanged(javax.swing.event.ChangeEvent evt) {                                                  
		this.autoLaunch = jCheckBox_autoLaunch.isSelected();
    }

    private void jButton_nextWaveActionPerformed(java.awt.event.ActionEvent evt) {
    }                                                

    private void jPanel_boardMouseClicked(java.awt.event.MouseEvent evt) {                                          
		this.mouseClicked(evt.getButton(), evt.getX(), evt.getY());
    }                                         

    private void jPanel_boardMouseMoved(java.awt.event.MouseEvent evt) {                                        
		this.gameBoard.requestFocusInWindow();
		if (this.placingTower || this.context.gameState == HexTD.gameState.editing) {
			int[] hexC = this.gameBoard.hexCoordsFromScreenCoords(evt.getX(), evt.getY());
			if (this.placingTower || this.context.gameState == HexTD.gameState.editing) {
				this.highLightHex(hexC);
			}
		}
    }                                       

    private void jPanel_boardComponentResized(java.awt.event.ComponentEvent evt) {                                              
		this.recalculateScale();
    }                                             

    private void formComponentResized(java.awt.event.ComponentEvent evt) {                                      
		//this.recalculateScale();
    }                                     

    private void jButton_postScoreActionPerformed(java.awt.event.ActionEvent evt) {                                                  
		this.postScore();
    }                                                 

    private void jButton_postReviewActionPerformed(java.awt.event.ActionEvent evt) {                                                   
		this.postCheck();
}                                                  

    private void jTextField_titleKeyTyped(java.awt.event.KeyEvent evt) {                                          
		this.context.levelTitle = this.jTextField_title.getText();
    }                                         

    private void jTextField_titleKeyReleased(java.awt.event.KeyEvent evt) {                                             
		this.context.levelTitle = this.jTextField_title.getText();
    }                                            
    // Variables declaration - do not modify
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JButton jButton_lostTryAgain;
    private javax.swing.JButton jButton_menu;
    private javax.swing.JButton jButton_nextWave;
    private javax.swing.JButton jButton_postReview;
    private javax.swing.JButton jButton_postScore;
    private javax.swing.JButton jButton_printMap;
    private javax.swing.JButton jButton_wonTryAgain;
    private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItem_background;
    private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItem_external;
    private javax.swing.JCheckBox jCheckBox_addLeft;
    private javax.swing.JCheckBox jCheckBox_addTop;
    private javax.swing.JCheckBox jCheckBox_autoLaunch;
    private javax.swing.JCheckBox jCheckBox_fastForward;
    private javax.swing.JCheckBox jCheckBox_replayPublic;
    private javax.swing.JFrame jFrame1;
    private javax.swing.JFrame jFrame_fullscreen;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel13;
    private javax.swing.JLabel jLabel14;
    private javax.swing.JLabel jLabel15;
    private javax.swing.JLabel jLabel16;
    private javax.swing.JLabel jLabel17;
    private javax.swing.JLabel jLabel18;
    private javax.swing.JLabel jLabel19;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel20;
    private javax.swing.JLabel jLabel21;
    private javax.swing.JLabel jLabel22;
    private javax.swing.JLabel jLabel23;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JLabel jLabel_bonus;
    private javax.swing.JLabel jLabel_credits;
    private javax.swing.JLabel jLabel_debug;
    private javax.swing.JLabel jLabel_gameTitle;
    private javax.swing.JLabel jLabel_interest;
    private javax.swing.JLabel jLabel_lives;
    private javax.swing.JLabel jLabel_score;
    private javax.swing.JLabel jLabel_submitFeedback;
    private javax.swing.JLabel jLabel_submitFeedback1;
    private javax.swing.JLabel jLabel_wave;
    private javax.swing.JMenuItem jMenuItem_ReplayCenter;
    private javax.swing.JMenuItem jMenuItem_editLevel;
    private javax.swing.JMenuItem jMenuItem_exitLevel;
    private javax.swing.JMenuItem jMenuItem_restartLevel;
    private hextd.UI.PanelLevelSelector jPanelLevelSelector;
    private hextd.UI.PanelPathEditor jPanelPathEditor;
    private hextd.UI.PanelTowerSelector jPanelTowerSelector;
    private javax.swing.JPanel jPanel_GameLost;
    private javax.swing.JPanel jPanel_GameWon;
    private javax.swing.JPanel jPanel_board;
    private javax.swing.JPanel jPanel_console;
    private javax.swing.JPanel jPanel_editor;
    private javax.swing.JPanel jPanel_externalMessage;
    private javax.swing.JPanel jPanel_gameButtons;
    private javax.swing.JPanel jPanel_gameInfo;
    private javax.swing.JPanel jPanel_gamePanel;
    private javax.swing.JPanel jPanel_replayEnded;
    private javax.swing.JPanel jPanel_submitReview;
    private javax.swing.JPanel jPanel_submitScore;
    private javax.swing.JPopupMenu jPopupMenu;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JSpinner jSpinner_height;
    private javax.swing.JSpinner jSpinner_interestIncrease;
    private javax.swing.JSpinner jSpinner_interestStart;
    private javax.swing.JSpinner jSpinner_lives;
    private javax.swing.JSpinner jSpinner_moneyStart;
    private javax.swing.JSpinner jSpinner_width;
    private javax.swing.JTextField jTextField_background;
    private javax.swing.JTextField jTextField_postUserName;
    private javax.swing.JTextField jTextField_title;
    private javax.swing.JTextPane jTextPane_output;
    private hextd.UI.PanelReplayControls panelReplayControls;
    private hextd.UI.PanelTowerInfo panelTowerInfo;
    private hextd.UI.PanelWaveInfo panelWaveInfo;
    // End of variables declaration                   
#endif

		private void NextWaveButton_Click(object sender, RoutedEventArgs e)
		{
			//this.nextWave();
		}
	}
}